#pragma once
#include <iostream>
#include <string>
#include <functional>
#include <cstdio>
#include <unistd.h>
#include "log.hpp"

//封装了Thread线程，更好的维护thread，让他自动构造和自动析构.并更简便启动线程和终止线程。
class ThreadData
{
    public:
    void* args_;//参数
    std::string name_;//名字
};
//typedef std::function<void*(void*)>fun_t;由于线程库只支持C接口的，所以C++11的包装器没办法用
typedef void*(*fun_t)(void*);

class Thread//用类似于智能指针的方法来包装线程，让其自动构造
{
    public:
    Thread(int num/*线程编号*/,fun_t callback/*线程例程函数*/,void* args):func_(callback)//传入线程的编号
    {
        char nameBuffer[64];
        snprintf(nameBuffer,sizeof nameBuffer,"Thread-%d",num);
        name_=nameBuffer;

        tdata_.args_=args;//外部传进来的参数-this指针
        tdata_.name_=name_;//线程名字
    }
    ~Thread()
    {
        //析构 会自动调自定义类型的默认析构
        //析构 对内置类型不处理，内置类型在结束后自动被系统处理
        //在本类中动态开辟的空间需要我们自己写析构来释放
    }
    std::string name()
    {
        return name_;
    }
    void start()//启动线程
    {
        pthread_create(&tid_,nullptr,func_,(void*)&tdata_);//传tadata_进去，让线程的例程函数获得，这样可以使线程在执行时可以打印自己的名字 和 外部的args参数信息。
    }
    void join()//终止线程
    {
        pthread_join(tid_,nullptr);
    }
    private:
    std::string name_;//线程名字
    fun_t func_;//线程回调方法
    ThreadData tdata_;
    pthread_t tid_;//线程id

};